#include "Material.h"
#include <GL/glew.h>
#include <iostream>

using namespace prog3d;
using namespace std;


Material::~Material() {};

Material::Material() {
  diffuse(Color(0.0,0.8,0.3));
  specular(Color(0,0,0.8));
  ambient(Color(0,0.2,0));
  shininess(45.0);
  setDescartes(0.0);
  setAttReflexion(0.0);
  setAttRefraction(0.0);
  _mapKd=NULL;
}

void Material::ambient(const Color &a) {
	ka=a;
}
void Material::diffuse(const Color &d) {
	kd=d;
}
void Material::specular(const Color &s) {
	ks=s;
}
void Material::shininess(double sh) {
	s=sh;
}

void Material::mapDiffuse(Texture *t) {
  _mapKd=t;
}

Texture *Material::mapDiffuse() {
  return _mapKd;
}

const Color &Material::ambient() const {
	return ka;
}
const Color &Material::diffuse() const {
	return kd;
}
const Color &Material::specular() const {
	return ks;
}
double Material::shininess() const {
	return s;
}


void Material::setDescartes(double n) {
	_descartes=n;
}

void Material::setAttReflexion(double alpha) {
	att_reflex=alpha;
}

void Material::setAttRefraction(double alpha) {
	att_refrac=alpha;
}

void Material::setMilieu(double m) {
    _milieu=m;
}

double Material::milieu() const {
    return _milieu;
}

double Material::attReflexion() const {
	return att_reflex;
}

double Material::attRefraction() const {
	return att_refrac;
}

double Material::alpha() const {
  return _alpha;
}

void Material::alpha(const double a) {
  _alpha=a;
}

void Material::setGL() {
  float tab[4];
  tab[0]=ambient().r();
  tab[1]=ambient().g();
  tab[2]=ambient().b();
  tab[3]=alpha();
  glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,tab);

  tab[0]=diffuse().r();
  tab[1]=diffuse().g();
  tab[2]=diffuse().b();
  tab[3]=alpha();
//  cout << "Diffuse = " << diffuse() << endl;
  glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,tab);

  tab[0]=specular().r();
  tab[1]=specular().g();
  tab[2]=specular().b();
  tab[3]=alpha();
  glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,tab);

  glMateriali(GL_FRONT_AND_BACK,GL_SHININESS,(int)shininess());

}

void Material::activeTexture() {
  if (_mapKd) {
    _mapKd->enable();
  }
}


void Material::name(const string &n) {
  _name=n;
}

string Material::name() const {
  return _name;
}

ostream& prog3d::operator <<(std::ostream &s,const Material &q) {
    s << "(a=" << q.ambient() << ",d=" << q.diffuse() << ",s=" << q.specular() << ")";
    return s;

}


